package pers.jing.android.helper

import pers.jing.android.helper.CmdTools.executeCommand
import pers.jing.android.helper.model.CommandResult
import java.io.File
import java.net.URLDecoder
import java.nio.charset.StandardCharsets

object AppUtils {

    /**
     * 用于Windows注册节点
     */
    const val INSTALL_WITH_ANDROID_HELPER = "InstallWithAndroidHelper"
    /**
     * 动态获取应用安装目录（调试/发布阶段通用）
     * @return 应用根目录路径（如：C:\Program Files\APKHelper 或 D:\Project\build\install\app）
     */
    fun getCurExeFilePath(): String? {
        return try {
            // 1. 获取当前类的加载路径（兼容 JAR/EXE/IDE 调试）
            val className = AppUtils::class.java.name.replace(".", "/") + ".class"
            //调试阶段-路径: file:/xxx/xxx/composeApp/build/libs/composeApp-jvm.jar!/pers/jing/android/helper/AppPathUtils.class
            val classResource = AppUtils::class.java.classLoader.getResource(className)
                ?: return null

            val path = classResource.path
                .let { URLDecoder.decode(it, "UTF-8") } // 解码 URL 特殊字符（如空格）
            println("first: $path")
            // 2. 根据运行环境解析路径
            return when {
                // 发布阶段：EXE 打包（如通过 jpackage 生成的可执行文件）
                path.contains("exe!") -> {
                    val exePath = path.substringAfter("file:/").substringBeforeLast("!")
                    File(exePath).absolutePath
                }
                // 发布阶段：JAR 包运行
                path.contains("jar!") -> {
                    val jarPath = path.substringAfter("file:/").substringBeforeLast("!")
                    File(jarPath).absolutePath
                }
                else -> null
            }
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     * 解析命令行中传入的数据
     */
    fun getParamConfig(args: Array<String>?): ParamConfig {
        if (args == null || args.isEmpty()) {
            return ParamConfig()
        }
        var install: Boolean? = null
        var apkPath: String? = null
        val size = args.size
        var index = 0
        while(index < size) {
            var item = args[index]
            //默认自增
            index++
            if (item == "--install") {
                //安装
                install = true
                if (index < size) {
                    item = args[index]
                    if (item.endsWith(".apk", true)) {
                        //仅当下一个参数是apk,才赋值, 并保存
                        apkPath = item
                        index++
                    }
                }
            }
        }
        return ParamConfig(install = install, apkPath = apkPath)
    }

    fun getJavaExecutablePath(): String? {
        val javaHome = System.getProperty("java.home")?: return null
        val osName = System.getProperty("os.name")
        val javaExecutable = when {
            osName.contains("windows", true) -> "\\bin\\java.exe"
            else -> "/bin/java"
        }
        return File(javaHome, javaExecutable).absolutePath
    }

    /**
     * 为apk文件添加菜单
     */
    suspend fun addApkContextMenu(): CommandResult {
        val osName = System.getProperty("os.name").lowercase()
        return when {
            osName.contains("windows") -> addApkContextMenuOnWindows()
            osName.contains("macos") -> addInstallApkMenuOnMacOS()
            osName.contains("linux") -> addInstallApkMenuOnLinux()
            else -> CommandResult(-1, error = listOf("暂不支持该系统"))
        }
    }

    private suspend fun addApkContextMenuOnWindows(): CommandResult {
        // 1. 获取应用 EXE 路径（KMP 打包后可通过 System.getProperty("user.dir") 或自定义路径）
        var appExePath = getCurExeFilePath()?: return CommandResult(-1, error = listOf("系统异常，未找到执行目录"))
        if (appExePath.endsWith(".jar")) {
            //调试阶段, 没有exe, 安装之后, jar位于安装目录app/composeApp-jvm-xxx.jar
            var file = File(appExePath)
            if (file.parentFile.exists()) {
                file = File(file.parentFile.parentFile, "AndroidHelper.exe")
                if (file.exists()) {
                    appExePath = file.absolutePath
                } else {
                    return CommandResult(-1, error = listOf("${file.absolutePath} not exits"))
                }
            } else {
                return CommandResult(-1, error = listOf("${file.parentFile.absolutePath} not exits"))
            }
        }

        // 2. 由于通过import导入注册脚本一直无法成功, 使用逐条命令执行
        val commands = listOf(
            // 步骤1：注册 .apk 关联到 APKFile
            listOf(
                "reg", "add",
                "HKCU\\Software\\Classes\\.apk",
                "/ve",  // /ve 表示设置默认值
                "/t", "REG_SZ",  // 字符串类型
                "/d", "APKFile",  // 值为 APKFile
                "/f"  // 强制覆盖，无需确认
            ),
            // 步骤2：定义 APKFile 类型描述
            listOf(
                "reg", "add",
                "HKCU\\Software\\Classes\\APKFile",
                "/ve",
                "/t", "REG_SZ",
                "/d", "APK 安装包",
                "/f"
            ),
            // 步骤3：创建右键菜单节点
            listOf(
                "reg", "add",
                "HKCU\\Software\\Classes\\APKFile\\shell\\$INSTALL_WITH_ANDROID_HELPER",
                "/ve",
                "/t", "REG_SZ",
                "/d", "通过 AndroidHelper 安装",
                "/f"
            ),
            // 步骤4：定义右键菜单执行命令
            listOf(
                "reg", "add",
                "HKCU\\Software\\Classes\\APKFile\\shell\\$INSTALL_WITH_ANDROID_HELPER\\command",
                "/ve",
                "/t", "REG_SZ",
                "/d", "\"$appExePath --install %1\"",  // 命令内容
                "/f"
            )
        )

        // 3. 逐行执行命令，记录错误
        var cResult = CommandResult(-1, error = listOf("未知错误"))
        commands.forEach { cmd ->
            cResult = executeCommand(cmd, charset("GBK"))
            if (cResult.code != 0) {
                val errorList = mutableListOf<String>(cmd.joinToString(" "))
                if (cResult.error != null) {
                    errorList.addAll(cResult.error)
                }
                return cResult.copy(error = errorList)
            }
        }
        return cResult
    }

    private fun addInstallApkMenuOnMacOS(): CommandResult {
        return CommandResult(-1, error = listOf("暂不支持该系统"))
    }

    private fun addInstallApkMenuOnLinux(): CommandResult {
        return CommandResult(-1, error = listOf("暂不支持该系统"))
    }


    suspend fun deleteApkContextMenu(): CommandResult {
        val osName = System.getProperty("os.name").lowercase()
        return when {
            osName.contains("windows") -> {
                val array = listOf("reg", "delete",
                    "HKCU\\APKFile\\shell\\$INSTALL_WITH_ANDROID_HELPER", "/f")
                executeCommand(array, charset("GBK"))
            }
            osName.contains("macos") -> CommandResult(-1, error = listOf("暂不支持该系统"))
            osName.contains("linux") -> CommandResult(-1, error = listOf("暂不支持该系统"))
            else -> CommandResult(-1, error = listOf("暂不支持该系统"))
        }
    }
}